package com.example.hello;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.res.AssetManager;
import android.os.Build;
import android.os.Bundle;
import android.speech.tts.Voice;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.hello.util.DeviceUtils;
import com.example.hello.util.FucUtil;
import com.example.hello.util.TaklUtils;
import com.iflytek.aiui.AIUIAgent;
import com.iflytek.aiui.AIUIConstant;
import com.iflytek.aiui.AIUIEvent;
import com.iflytek.aiui.AIUIListener;
import com.iflytek.aiui.AIUIMessage;
import com.iflytek.aiui.AIUISetting;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

public class TalkActivity extends AppCompatActivity {


    //聊天列表对象
    private LinearLayout talkList;
    private static String TAG = MainActivity.class.getSimpleName();
    private Toast mToast;
    private AIUIAgent mAIUIAgent = null;
    private boolean mIsWakeupEnable = false;
    private int mAIUIState = AIUIConstant.STATE_IDLE;
    private String mSyncSid = "";

    private TextView leftTV;
    private TextView rightTV;
    private ScrollView scrollView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_talk);

        //获取聊天列表组件对象
        talkList = findViewById(R.id.talkList);

        mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
// 加载权限
        requestPermissions();


        final TextView voiceBtn = findViewById(R.id.voiceBtn);
        final EditText textET = findViewById(R.id.textET);
        final TextView sendBtn = findViewById(R.id.sendBtn);
        final LinearLayout textLL = findViewById(R.id.textLL);
        //获取开始聊天按钮组件对象
        final Button talkBtn = findViewById(R.id.talkBtn);

        //给语音按钮点击添加监听事件
        voiceBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TextView tv = (TextView) v;
                if ("语音".equals(tv.getText())) {
                    //隐藏文本框和发送按钮
                    textLL.setVisibility(View.GONE);
                    talkBtn.setVisibility(View.VISIBLE);
                    tv.setText("文本");
//                   // sendBtn.setVisibility(View.INVISIBLE);
                } else {
                    //显示文本框和发送框
                    textLL.setVisibility(View.VISIBLE);
                    //隐藏y聊天按钮
                    talkBtn.setVisibility(View.GONE);
                    tv.setText("语音");
                }

            }
        });

        //给发送按钮点击添加监听事件
        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String text = textET.getText().toString();
                if (text.isEmpty()) {
                    showTip("请输入要发送的文本信息");
                    return;
                }

                //创建AIUIAgent对象
                createAgent();
                //调用文本处理方法
                startTextNlp(text);
                //清空输入框内容
                textET.setText("");

            }
        });


//        //请求权限
//        requestPermissions();


        //给聊天按钮添加触摸监听事件
        talkBtn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN://手指按下按钮
                        //创建AIUIAgent对象
                        createAgent();
                        //开始语音聊天
                        startVoiceNlp();
                        break;
                    case MotionEvent.ACTION_UP://手指抬起
                        //结束语言聊天
                        stopVoiceNlp();
                        break;
                }
                return true;
            }
        });


        //隐藏头部标题栏
        ActionBar bar = getSupportActionBar();
        if (null != bar) {
            bar.hide();
        }


    }

    //设置右边聊天内容
    private void setRightMsg(String msg) {
        //构建右边聊天内存
        View rightView = LayoutInflater.from(TalkActivity.this).inflate(R.layout.right_talk_layout, talkList, false);
        TextView rightTV = rightView.findViewById(R.id.rightTV);
        rightTV.setText(msg);
        talkList.addView(rightView);
    }

    //设置左边聊天内容
    private void setLeftMsg(String msg) {
        //构建左边聊天内存
        View leftView = LayoutInflater.from(TalkActivity.this).inflate(R.layout.left_talk_layout, talkList, false);
        TextView leftTV = leftView.findViewById(R.id.leftTV);
        leftTV.setText(msg);
        talkList.addView(leftView);
    }

    /**
     * 申请权限
     */
    private void requestPermissions() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                ActivityCompat.requestPermissions(this, new String[]{
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.RECORD_AUDIO,
                        Manifest.permission.INTERNET,
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.ACCESS_NETWORK_STATE
                }, 0x0010);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void createAgent() {
        if (null == mAIUIAgent) {
            Log.i(TAG, "create aiui agent");

            //为每一个设备设置对应唯一的SN（最好使用设备硬件信息(mac地址，设备序列号等）生成），以便正确统计装机量，避免刷机或者应用卸载重装导致装机量重复计数
            AIUISetting.setSystemInfo(AIUIConstant.KEY_SERIAL_NUM, DeviceUtils.getWifiMac(this));
            mAIUIAgent = AIUIAgent.createAgent(this, getAIUIParams(), mAIUIListener);
        }

        if (null == mAIUIAgent) {
            final String strErrorTip = "创建AIUIAgent失败！";
            showTip(strErrorTip);

            setRightMsg(strErrorTip);
        } else {
            showTip("AIUIAgent已创建");
        }
    }

    private void showTip(final String str) {
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                mToast.setText(str);
                mToast.show();
            }
        });
    }

    private String getAIUIParams() {
        String params = "";

        AssetManager assetManager = getResources().getAssets();
        try {
            InputStream ins = assetManager.open("cfg/aiui_phone.cfg");
            byte[] buffer = new byte[ins.available()];

            ins.read(buffer);
            ins.close();

            params = new String(buffer);

            JSONObject paramsJson = new JSONObject(params);

            mIsWakeupEnable = !"off".equals(paramsJson.optJSONObject("speech").optString("wakeup_mode"));
            if (mIsWakeupEnable) {
                FucUtil.copyAssetFolder(this, "ivw", "/sdcard/AIUI/ivw");
            }

            params = paramsJson.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return params;
    }


    //7、创建AIUI监听器对象
    private AIUIListener mAIUIListener = new AIUIListener() {

        @Override
        public void onEvent(AIUIEvent event) {
            Log.i(TAG, "on event: " + event.eventType);

            switch (event.eventType) {
                case AIUIConstant.EVENT_CONNECTED_TO_SERVER:
                    showTip("已连接服务器");
                    break;

                case AIUIConstant.EVENT_SERVER_DISCONNECTED:
                    showTip("与服务器断连");
                    break;

                case AIUIConstant.EVENT_WAKEUP:
                    showTip("进入识别状态");
                    break;

                case AIUIConstant.EVENT_RESULT: {
                    try {
                        JSONObject bizParamJson = new JSONObject(event.info);
                        JSONObject data = bizParamJson.getJSONArray("data").getJSONObject(0);
                        JSONObject params = data.getJSONObject("params");
                        JSONObject content = data.getJSONArray("content").getJSONObject(0);
                        String sub = params.optString("sub");

                        if (content.has("cnt_id") && !"tts".equals(sub)) {
                            String cnt_id = content.getString("cnt_id");
                            String cntStr = new String(event.data.getByteArray(cnt_id), "utf-8");

                            // 获取该路会话的id，将其提供给支持人员，有助于问题排查
                            // 也可以从Json结果中看到
                            String sid = event.data.getString("sid");
                            String tag = event.data.getString("tag");

                            //Log.i(TAG, tag);

                            if (TextUtils.isEmpty(cntStr)) {
                                return;
                            }

                            JSONObject cntJson = new JSONObject(cntStr);

                            // 显示回答信息
                            Log.i(TAG, cntJson.toString());
                            if ("iat".equals(sub)) {
                                String askContent = TaklUtils.processIATResult(cntJson);
                                if (null != askContent && !"".equals(askContent)) {
                                    setRightMsg(askContent);
                                }
                            } else if ("nlp".equals(sub)) {
                                // 解析得到语义结果
                                String answer = TaklUtils.processNlpResult(cntJson);
                                if (null != answer && !"".equals(answer)) {
                                    setLeftMsg(answer);
                                }
                            }
                        }
                    } catch (Throwable e) {
                        e.printStackTrace();
                        Log.i(TAG, e.getLocalizedMessage());
                    }

                }
                break;

                case AIUIConstant.EVENT_ERROR: {
                    Log.i(TAG, "错误: " + event.arg1 + "\n" + event.info);
                }
                break;

                case AIUIConstant.EVENT_VAD: {
                    if (AIUIConstant.VAD_BOS == event.arg1) {
                        showTip("找到vad_bos");
                    } else if (AIUIConstant.VAD_EOS == event.arg1) {
                        showTip("找到vad_eos");
                    } else {
                        showTip("" + event.arg2);
                    }
                }
                break;

                case AIUIConstant.EVENT_START_RECORD: {
                    showTip("已开始录音");
                }
                break;

                case AIUIConstant.EVENT_STOP_RECORD: {
                    showTip("已停止录音");
                }
                break;

                case AIUIConstant.EVENT_STATE: {    // 状态事件
                    mAIUIState = event.arg1;

                    if (AIUIConstant.STATE_IDLE == mAIUIState) {
                        // 闲置状态，AIUI未开启
                        showTip("STATE_IDLE");
                    } else if (AIUIConstant.STATE_READY == mAIUIState) {
                        // AIUI已就绪，等待唤醒
                        showTip("STATE_READY");
                    } else if (AIUIConstant.STATE_WORKING == mAIUIState) {
                        // AIUI工作中，可进行交互
                        showTip("STATE_WORKING");
                    }
                }
                break;
                default:
                    break;
            }
        }

    };


    //8、调用AIUIAgent对象进行语义理解
    private void startTextNlp(String text) {
        if (null == mAIUIAgent) {
            showTip("AIUIAgent 为空，请先创建");
            return;
        }

        // 先发送唤醒消息，改变AIUI内部状态，只有唤醒状态才能接收文本输入
//		if (AIUIConstant.STATE_WORKING != mAIUIState)
        {
            AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
            mAIUIAgent.sendMessage(wakeupMsg);
        }

        Log.i(TAG, "start text nlp");
//        String text = "南宁明天的天气怎么样？";
        setRightMsg(text);

        try {
            // 在输入参数中设置tag，则对应结果中也将携带该tag，可用于关联输入输出
            String params = "data_type=text,tag=text-tag";
            byte[] textData = text.getBytes("utf-8");

            AIUIMessage write = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, params, textData);
            mAIUIAgent.sendMessage(write);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    //9、调用语音聊天功能
    private void startVoiceNlp() {
        if (null == mAIUIAgent) {
            showTip("AIUIAgent为空，请先创建");
            return;
        }

        Log.i(TAG, "start voice nlp");


        // 先发送唤醒消息，改变AIUI内部状态，只有唤醒状态才能接收语音输入
        // 默认为oneshot模式，即一次唤醒后就进入休眠。可以修改aiui_phone.cfg中speech参数的interact_mode为continuous以支持持续交互
        if (!mIsWakeupEnable) {
            AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
            mAIUIAgent.sendMessage(wakeupMsg);
        }

        // 打开AIUI内部录音机，开始录音。若要使用上传的个性化资源增强识别效果，则在参数中添加pers_param设置
        // 个性化资源使用方法可参见http://doc.xfyun.cn/aiui_mobile/的用户个性化章节
        // 在输入参数中设置tag，则对应结果中也将携带该tag，可用于关联输入输出
        String params = "sample_rate=16000,data_type=audio,pers_param={\"uid\":\"\"},tag=audio-tag";
        AIUIMessage startRecord = new AIUIMessage(AIUIConstant.CMD_START_RECORD, 0, 0, params, null);

        mAIUIAgent.sendMessage(startRecord);
    }

    private void stopVoiceNlp() {
        if (null == mAIUIAgent) {
            showTip("AIUIAgent 为空，请先创建");
            return;
        }

        Log.i(TAG, "stop voice nlp");
        // 停止录音
        String params = "sample_rate=16000,data_type=audio";
        AIUIMessage stopRecord = new AIUIMessage(AIUIConstant.CMD_STOP_RECORD, 0, 0, params, null);

        mAIUIAgent.sendMessage(stopRecord);
    }

    private void destroyAgent() {
        if (null != mAIUIAgent) {
            Log.i(TAG, "destroy aiui agent");

            mAIUIAgent.destroy();
            mAIUIAgent = null;

            showTip("AIUIAgent已销毁");
        } else {
            showTip("AIUIAgent为空");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        destroyAgent();
//        if( null != mAIUIAgent ){
//            mAIUIAgent.destroy();
//            mAIUIAgent = null;
//        }
    }
}